from typing import Dict, Any
import cv2
import numpy as np
from paddleocr import PPStructureV3

from app.utils.exceptions import ImageProcessingError
from app.utils.logger import get_logger

logger = get_logger(__name__)


# 表格结构识别模块
class TableStructureRecognitionModule:
    _instance = None
    _initialized = False

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(TableStructureRecognitionModule, cls).__new__(cls)
        return cls._instance

    def __init__(self):
        if not self._initialized:
            logger.info("Initializing TableStructureModule")
            self.table_ocr = None
            self._model_initialized = False
            self._initialized = True

    def _initialize_model(self):
        """延迟初始化模型"""
        if not self._model_initialized:
            logger.info("Initializing PPStructureV3 table model")
            self.table_ocr = PPStructureV3(table=True)
            self._model_initialized = True

    def recognize(
            self,
            image_data: bytes,
            detect_tables: bool = True,
            detect_formulas: bool = True,
            structure_only: bool = True,
    ) -> Dict[str, Any]:
        """执行表格结构识别"""
        try:
            # 将字节数据转换为OpenCV图像
            nparr = np.frombuffer(image_data, np.uint8)
            img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)

            if img is None:
                raise ImageProcessingError("Failed to decode image data")
            height, width = img.shape[:2]

            from paddleocr import TableStructureRecognition
            model = TableStructureRecognition(model_name="SLANet")
            result = model.predict(input=img, batch_size=1)

            # 提取结构化数据
            layout_elements = []
            for res in result:
                # 获取结构化HTML
                html = res.res['structure'] if 'structure' in res.res else ''
                bbox = res.bbox
                score = res.res['structure_score'] if 'structure_score' in res.res else 0.0

                # 构建可序列化的字典
                layout_element = {
                    "type": "table",
                    "bbox": bbox,
                    "confidence": float(score),
                    "html": "".join(html) if isinstance(html, list) else html
                }
                layout_elements.append(layout_element)

            return {
                "layout_elements": layout_elements,
                "image_size": {"width": width, "height": height}
            }

        except Exception as e:
            logger.exception(f"Layout analysis failed: {str(e)}")
            raise ImageProcessingError(f"Layout analysis failed: {str(e)}")